package listeners;

import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeProperty;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class TestLEvaluatorWithProps {

    public static class EvaluatorWithProps extends LExprBaseListener {

        ParseTreeProperty<Integer> values = new ParseTreeProperty<>();

        public void setValue(ParseTree node, int value) {
            values.put(node, value);
        }

        public int getValue(ParseTree node) {
            return values.get(node);
        }

        @Override
        public void exitS(LExprParser.SContext context) {
            setValue(context, getValue(context.e()));
        }

        @Override
        public void exitMult(LExprParser.MultContext context) {
            int left = getValue(context.e(0));
            int right = getValue(context.e(1));
            setValue(context, left * right);
        }

        @Override
        public void exitAdd(LExprParser.AddContext context) {
            int left = getValue(context.e(0));
            int right = getValue(context.e(1));
            setValue(context, left + right);
        }

        @Override
        public void exitInt(LExprParser.IntContext context) {
            String intText = context.INT().getText();
            setValue(context, Integer.parseInt(intText));
        }
    }

    // calculator

    public static void main(String[] args) throws IOException {
        String inputFile = null;
        if (args.length > 0) {
            inputFile = args[0];
        }
        InputStream is = System.in;
        if(inputFile != null) {
            is = new FileInputStream(inputFile);
        }

        CharStream input = CharStreams.fromStream(is);
        LExprLexer lexer = new LExprLexer(input);
        CommonTokenStream tokenStream = new CommonTokenStream(lexer);
        LExprParser parser = new LExprParser(tokenStream);
        ParseTree tree = parser.s();

        System.out.println(tree.toStringTree(parser));
        ParseTreeWalker walker = new ParseTreeWalker();
        EvaluatorWithProps evaluatorWithProps = new EvaluatorWithProps();
        walker.walk(evaluatorWithProps, tree);
        System.out.println("properties result = " + evaluatorWithProps.getValue(tree));
    }

}
